import os
import requests
import logging
from pydantic import Field
from mcp.server.fastmcp import FastMCP, Image
from mcp.server.fastmcp.server import Settings
from logging.handlers import RotatingFileHandler
from io import BytesIO
from PIL import Image as PILImage

# Create an MCP server
mcp = FastMCP("Unionpay-mcp-server")
PROXY_MAIN_URL = "http://127.0.0.1:20011/execute"

settings = Settings()
settings.debug = True
settings.host = "0.0.0.0"
settings.port = 20012
# set
mcp.settings = settings

log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)

# 创建日志记录器
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

file_handler = RotatingFileHandler(
    os.path.join(log_dir, "unionpay_sse_api.log")
)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)


# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """Get a personalized greeting"""
    return f"Hello, {name}!"


@mcp.tool()
def create_contract_order_unionpay_payment(
        orderId: str = Field(description="交易订单号,格式:8~40位字母数字"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        certifTp: str = Field(description="证件类型,格式:2位数字"),
        certifId: str = Field(description="证件号码,格式:1~20位字母数字"),
        customerNm: str = Field(description="用户姓名,格式:1~120字母数字"),
        phoneNo: str = Field(description="手机号,格式:1~20位手机号"),
        riskRateInfo: str = Field(default="", description="风险信息域的JSON字符串格式")):
    """
    创建一笔签约支付订单，并返回授权签约链接
    """
    name = "create-contract-order-unionpay-payment"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "certifTp": certifTp,
                "certifId": certifId,
                "customerNm": customerNm,
                "phoneNo": phoneNo,
                "riskRateInfo": riskRateInfo
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return "https://www.baidu.com"


@mcp.tool()
def create_contract_unionpay_payment(
        orderId: str = Field(description="交易订单号,格式:8~40位字母数字"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        origOrderId: str = Field(description="签约下单交易请求的订单号orderId"),
        origTxnTime: str = Field(description="签约下单交易应答的txnTime"),
        tokenType: str = Field(description="token类型,格式:2位数字")):
    """
    发起签约交易，并返回签约信息,该交易是签约下单的后续交易，是支付的前序交易，且签约交易只需做一次，可以实现多次
    """
    name = "create-contract-unionpay-payment"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "origOrderId": origOrderId,
                "origTxnTime": origTxnTime,
                "tokenType": tokenType
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def pay_contract_order_unionpay_payment(
        orderId: str = Field(description="商户订单号"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        txnAmt: str = Field(description="用户发起的本次交易额度,单位元"),
        token: str = Field(description="签约完成时候返回的用户token"),
        customerNm: str = Field(default="", description="支付用户个人信息，用户名"),
        currencyCode: str = Field(default="", description="交易币种，选送"),
        phoneNo: str = Field(default="", description="支付用户个人信息，手机号"),
        certifTp: str = Field(default="", description="支付用户个人信息，证件类型"),
        certifId: str = Field(default="", description="支付用户个人信息，证件号"),
        riskRateInfo: str = Field(default="", description="风险信息域的JSON字符串格式")):
    """
    创建一笔签约支付订单，并返回用户支付结果
    """
    name = "pay-contract-order-unionpay-payment"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "txnAmt": txnAmt,
                "token": token,
                "customerNm": customerNm,
                "currencyCode": currencyCode,
                "phoneNo": phoneNo,
                "certifTp": certifTp,
                "certifId": certifId,
                "riskRateInfo": riskRateInfo
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def cancel_contract_order_unionpay_payment(
        orderId: str = Field(description="商户订单号"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        token: str = Field(description="签约完成时候返回的用户token")):
    """
    创建一笔解约订单，并返回解约结果,该交易是签约的反向交易
    """
    name = "cancel-contract-order-unionpay-payment"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "token": token
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def refund_contract_order_unionpay_payment(
        orderId: str = Field(description="商户订单号"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        origTxnTime: str = Field(default="", description="待退货的订单发起时间"),
        origOrderId: str = Field(default="", description="待退货的订单号"),
        txnAmt: str = Field(description="需要退货的金额"),
        origTn: str = Field(default="", description="银联受理订单号，支付交易返回时携带")):
    """
    创建一笔退货订单，并返回退货结果。上送银联受理订单号或原始商户订单号+原始订单交易时间即可发起退货
    """
    name = "refund-contract-order-unionpay-payment"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "origTxnTime": origTxnTime,
                "origOrderId": origOrderId,
                "txnAmt": txnAmt,
                "origTn": origTn
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def query_unionpay_payment(
        orderId: str = Field(description="被查询交易订单号,原交易订单号,例如如查询支付交易,填支付交易orderId"),
        txnTime: str = Field(default="",
                             description="被查询交易交易时间,原交易时间,如查询支付交易,填支付交易txnTime")):
    """
    发起查询交易，支持签约交易查询、支付交易查询、退款等查询类交易
    """
    name = "query-unionpay-payment"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def contract_pay_sms(
        orderId: str = Field(description="交易订单号,格式:8~40位字母数字"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        token: str = Field(description="签约交易返回的token"),
        txnAmt: str = Field(description="交易金额"),
        currencyCode: str = Field(default="156", description="交易币种,默认156")):
    """
    创建一笔支付短信，当需要在支付前做短信验证时调用此接口
    """
    name = "contract-pay-sms"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "token": token,
                "txnAmt": txnAmt,
                "currencyCode": currencyCode
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def apply_unionpay_qrCode(
        orderId: str = Field(description="交易订单号,格式:8~40位字母数字"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        payTimeout: str = Field(default="", description="二维码有效时间,格式:YYYYMMDDhhmmss"),
        txnAmt: str = Field(default="", description="交易金额,单位元")):
    """
    申请消费二维码,返回qrCode
    """
    name = "apply-unionpay-qrCode"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "payTimeout": payTimeout,
                "txnAmt": txnAmt
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    try:
        # 本地二维码图片路径
        image_path = "./img.png"


        img = PILImage.open(image_path)
        img.thumbnail((300, 300))
        buffer = BytesIO()
        img.save(buffer, format="PNG")
        return Image(data=buffer.getvalue(), format="png")

    except Exception as e:
        logger.error(f"Failed to read QR code image: {e}")
        return None

    # return response_data


@mcp.tool()
def query_unionpay_QrCode_trade(
        orderId: str = Field(default="",
                             description="被查询交易订单号,原交易订单号,当使用原交易orderId和txnTime查询时必填"),
        txnTime: str = Field(default="",
                             description="被查询交易交易时间,原交易时间,当使用原交易orderId和txnTime查询时必填"),
        queryId: str = Field(default="", description="被查询交易流水号,当使用原交易流水号查询时必填")):
    """
    发起二维码类查询交易，支持申码支付交易查询、退款等查询类交易
    """
    name = "query-unionpay-QrCode-trade"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "queryId": queryId
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


@mcp.tool()
def refund_unionpay_qrCode(
        orderId: str = Field(description="交易订单号,格式:8~40位字母数字"),
        txnTime: str = Field(default="", description="交易时间,格式:yyyyMMddHHmmss"),
        origTxnTime: str = Field(default="", description="原始交易的交易时间,格式:YYYYMMDDhhmmss"),
        origOrderId: str = Field(default="", description="原始交易的订单号,格式:8~40位字母数字"),
        origQryId: str = Field(default="", description="原始交易的查询ID,格式:查询订单请求返回的若干位数字"),
        txnAmt: str = Field(description="待退货金额,单位元")):
    """
    对之前二维码交易进行退货，仅30天之内交易可退货，多次退货累计退货金额不超过原始交易金额
    """
    name = "refund-unionpay-qrCode"
    command = "tools/call"
    params = {
        "name": name,
        "arguments":
            {
                "orderId": orderId,
                "txnTime": txnTime,
                "origTxnTime": origTxnTime,
                "origOrderId": origOrderId,
                "origQryId": origQryId,
                "txnAmt": txnAmt
            },
        "_meta":
            {
                "progressToken": 2
            }
    }
    response = requests.post(PROXY_MAIN_URL, json={"command": command, "params": params})
    response_data = response.json()
    logger.info(f"{name}---{response_data}")
    return response_data


if __name__ == "__main__":
    mcp.run(transport="sse")
